/********************************** (C) COPYRIGHT *******************************
 * File Name          : ch32v30x_usbhs_device.c
 * Author             : WCH
 * Version            : V1.0.0
 * Date               : 2021/06/06
 * Description        : USB高速操作相关文件
 * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
 * SPDX-License-Identifier: Apache-2.0
 *******************************************************************************/
#include "ch32v30x_usbhs_device.h"

/******************************************************************************/
/* 常、变量定义 */

/* 函数声明 */
void USBHS_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
extern void SystemUpdate(UPDATA *updata);
/* USB缓冲区定义 */
__attribute__((aligned(4))) UINT8 EP0_Databuf[USBHS_UEP0_SIZE];        /* 端点0数据收发缓冲区 */
__attribute__((aligned(4))) UINT8 EP1_Rx_Databuf[USBHS_MAX_PACK_SIZE]; /* 端点1数据接收缓冲区 */
__attribute__((aligned(4))) UINT8 EP1_Tx_Databuf[USBHS_MAX_PACK_SIZE]; /* 端点1数据发送缓冲区 */

#define pMySetupReqPak ((PUSB_SETUP_REQ)EP0_Databuf)
#define RepDescSize 913

const UINT8 *pDescr;

volatile UINT8 HID_SET_REPORT_Flag = 0x0; /* SET REPROT 状态码   */

volatile UINT8 USBHS_Dev_SetupReqCode = 0xFF;   /* USB2.0高速设备Setup包命令码 */
volatile UINT16 USBHS_Dev_SetupReqLen = 0x00;   /* USB2.0高速设备Setup包长度 */
volatile UINT8 USBHS_Dev_SetupReqValueH = 0x00; /* USB2.0高速设备Setup包Value高字节 */
volatile UINT8 USBHS_Dev_Config = 0x00;         /* USB2.0高速设备配置值 */
volatile UINT8 USBHS_Dev_Address = 0x00;        /* USB2.0高速设备地址值 */
volatile UINT8 USBHS_Dev_SleepStatus = 0x00;    /* USB2.0高速设备睡眠状态 */
volatile UINT8 USBHS_Dev_EnumStatus = 0x00;     /* USB2.0高速设备枚举状态 */
volatile UINT8 USBHS_Dev_Endp0_Tog = 0x01;      /* USB2.0高速设备端点0同步标志 */
volatile UINT8 USBHS_Dev_Speed = 0x01;          /* USB2.0高速设备速度 */
volatile UINT8 USBHS_Int_Flag = 0x00;           /* USB2.0高速设备中断标志 */

volatile UINT16 USBHS_Endp1_Up_Flag = 0x00;  /* USB2.0高速设备端点1数据上传状态: 0:空闲; 1:正在上传; */
volatile UINT8 USBHS_Endp1_Down_Flag = 0x00; /* USB2.0高速设备端点1下传成功标志 */
volatile UINT8 USBHS_Endp1_Down_Len = 0x00;  /* USB2.0高速设备端点1下传长度 */
volatile BOOL USBHS_Endp1_T_Tog = 0;         /* USB2.0高速设备端点1发送tog位翻转 */
volatile BOOL USBHS_Endp1_R_Tog = 0;

/******************************************************************************/
/* USB设备描述符 */
UINT8 MyDevDescr[18] =
    {
        0x12,       //描述符大小
        0x01,       //描述符类型  1：设备描述符
        0x00, 0x02, // USB版本号 2.0 = 0200 1.1 = 0110
        0xEF,       // USB类型代码 0：配置描述符里 EF:复合设备 0x02:CDC设备
        0x02,       // USB子类代码 0：配置描述符里 02:复合设备 0x00:CDC设备
        0x01,       //协议代码    0：配置描述符里 01:复合设备 0x00:CDC设备
        0x40,       //端点0大小 64d
        0x88, 0x1A, // VID
        0xE1, 0xE6, // PID
        0x00, 0x11, //序列号
        0x01,       //厂商描述字符串
        0x02,       //产品描述字符串
        0x00,       //设备序列号字符串
        0x01        //配置字符串数量
};

/* USB配置描述符(高速) */
UINT8 MyCfgDescr_HS[] =
    {
        /*描述符大小 类型  总大小   接口数  参数 字符串 供电模式 电流大小单位2mA*/
        0x09, 0x02, 0x51, 0x00, 0x01, 0x01, 0x00, 0xA0, 0x32,                                      /* Config Desc */
        0x09, 0x04, 0x00, 0x00, 0x02, 0x03, 0x01, 0x01, 0x00,                                      /* Interface Desc */
        0x09, 0x21, 0x10, 0x01, 0x00, 0x01, 0x22, (UINT8)RepDescSize, (UINT8)(RepDescSize >> 8),   /* HID Desc */
        0x07, 0x05, 0x81, 0x03, (UINT8)DEF_USB_HS_EP_SIZE, (UINT8)(DEF_USB_HS_EP_SIZE >> 8), 0x01, //高速模式端点大小；DEF_USB_HS_EP_SIZE
        0x07, 0x05, 0x01, 0x03, (UINT8)DEF_USB_HS_EP_SIZE, (UINT8)(DEF_USB_HS_EP_SIZE >> 8), 0x01, //全速模式端点大小； DEF_USB_FS_EP_SIZE
};
//力反馈描述符  1226
// /*
const UINT8 reprot[] = {
    0x06, 0x00, 0xFF, // Usage Page (Vendor Defined 0xFF00)
    0x09, 0x01,       // Usage (0x01)
    0xA1, 0x01,       // Collection (Application)
    0x85, 0x01,       //   Report ID (1)
    0x09, 0x01,       //   Usage (0x01)
    0x15, 0x00,       //   Logical Minimum (0)
    0x26, 0xFF, 0x00, //   Logical Maximum (255)
    0x75, 0x08,       //   Report Size (8)
    0x95, 0x08,       //   Report Count (8)
    0x81, 0x02,       //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
    0xA1, 0x02,       //   Collection (Logical)
    0x85, 0x02,       //     Report ID (2)
    0x09, 0x02,       //     Usage (0x02)
    0x15, 0x00,       //     Logical Minimum (0)
    0x26, 0xFF, 0x00, //     Logical Maximum (255)
    0x75, 0x08,       //     Report Size (8)
    0x95, 0x03,       //     Report Count (3)
    0x81, 0x02,       //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
    0xC0,             //   End Collection
    0xA1, 0x02,       //   Collection (Logical)
    0x09, 0x01,       //     Usage (0x01)
    0x85, 0x01,       //     Report ID (1)
    0x26, 0xFF, 0x00, //     Logical Maximum (255)
    0x75, 0x08,       //     Report Size (8)
    0x95, 0x03,       //     Report Count (3)
    0x92, 0x02, 0x01, //     Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile,Buffered Bytes)
    0xC0,             //   End Collection
    0xA1, 0x02,       //   Collection (Logical)
    0x09, 0x02,       //     Usage (0x02)
    0x85, 0x02,       //     Report ID (2)
    0x26, 0xFF, 0x00, //     Logical Maximum (255)
    0x75, 0x08,       //     Report Size (8)
    0x95, 0x03,       //     Report Count (3)
    0x92, 0x02, 0x01, //     Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile,Buffered Bytes)
    0xC0,             //   End Collection
    0xA1, 0x02,       //   Collection (Logical)
    0x09, 0x03,       //     Usage (0x03)
    0x85, 0x03,       //     Report ID (3)
    0x26, 0xFF, 0x00, //     Logical Maximum (255)
    0x75, 0x08,       //     Report Size (8)
    0x96, 0x07, 0x01, //     Report Count (263)
    0x92, 0x02, 0x01, //     Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile,Buffered Bytes)
    0xC0,             //   End Collection
    0xC0,             // End Collection

    // 93 bytes

};

/* USB语言字符串描述符 */
const UINT8 MyLangDescr[] = {0x04, 0x03, 0x09, 0x04};

/* USB产商字符串描述符 */
const UINT8 MyManuInfo[] =
    {
        /* wch.cn */
        14, 03, 'B', 0, 'I', 0, 'N', 0, 'G', 0, '.', 0};

/* USB产品字符串描述符 */
const UINT8 MyProdInfo[] =
    {
        /* WCH USB2.0 DEVICE */
        38, 03, 'P', 0, 'r', 0, 'o', 0, ' ', 0, 'C', 0, 'o', 0, 'n', 0, 't', 0, 'r', 0, 'o', 0, 'l', 0, ' ', 0, 'D', 0, 'F', 0, 'U', 0, ' ', 0, 'S', 0};

/* USB序列号字符串描述符 */
const UINT8 MySerNumInfo[] =
    {
        /* 0123456789 */
        22, 03, 48, 0, 49, 0, 50, 0, 51, 0, 'E', 0, 53, 0, 'B', 0, 55, 0, 56, 0, 57, 0};

/* USB设备限定描述符 */
const UINT8 MyUSBQUADesc[] =
    {
        0x0A,
        0x06,
        0x00,
        0x02,
        0xFF,
        0x00,
        0xFF,
        0x40,
        0x01,
        0x00,
};

/* BOS描述符 */
const UINT8 MyBOSDesc[] =
    {
        0x05,
        0x0f,
        0x16,
        0x00,
        0x02,
        0x07,
        0x10,
        0x02,
        0x02,
        0x00,
        0x00,
        0x00,
        0x0a,
        0x10,
        0x03,
        0x00,
        0x0e,
        0x00,
        0x01,
        0x0a,
        0xff,
        0x07,
};

/* USB高速模式,其他速度配置描述符 */
UINT8 TAB_USB_HS_OSC_DESC[sizeof(MyCfgDescr_HS)] =
    {
        0x09, 0x07, /* 其他部分通过程序复制 */
};

/*********************************************************************
 * @fn      USBHS_RCC_Init
 *
 * @brief   Initializes the clock for USB2.0 High speed device.
 *
 * @return  none
 */
void USBHS_RCC_Init(void)
{
#if 0
    RCC->CFGR2 = USBHS_PLL_SRC_HSI | USBHS_PLL_SRC_PRE_DIV1 | USBHS_PLL_CKREF_4M; /* PLL REF = HSE/2 = 4MHz */
    RCC->CFGR2 |= USB_48M_CLK_SRC_PHY | USBHS_PLL_ALIVE;
    RCC->AHBPCENR |= ( (uint32_t)( 1 << 11 ) );
#else
    RCC_USBCLK48MConfig(RCC_USBCLK48MCLKSource_USBPHY);
    RCC_USBHSPLLCLKConfig(RCC_HSBHSPLLCLKSource_HSE);
    RCC_USBHSConfig(RCC_USBPLL_Div1);
    RCC_USBHSPLLCKREFCLKConfig(RCC_USBHSPLLCKREFCLK_8M);
    RCC_USBHSPHYPLLALIVEcmd(ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_USBHS, ENABLE);
//    RCC_AHBPeriphClockCmd( RCC_AHBPeriph_OTG_FS, ENABLE );
#endif
    Delay_Us(200);
}

/*********************************************************************
 * @fn      USBHS_Device_Endp_Init
 *
 * @brief   USB2.0高速设备端点初始化
 *
 * @return  none
 */
void USBHS_Device_Endp_Init(void)
{
    /* 使能端点1、端点2发送和接收  */
    USBHSD->ENDP_CONFIG = USBHS_EP0_T_EN | USBHS_EP0_R_EN | USBHS_EP1_T_EN | USBHS_EP2_T_EN | USBHS_EP1_R_EN | USBHS_EP2_R_EN;

    /* 端点非同步端点 */
    USBHSD->ENDP_TYPE = 0x00;

    /* 端点缓冲区模式，非双缓冲区，ISO传输BUF模式需要指定0  */
    USBHSD->BUF_MODE = 0x00;

    /* 端点最大长度包配置 */
    USBHSD->UEP0_MAX_LEN = 64;
    USBHSD->UEP1_MAX_LEN = 512;
    USBHSD->UEP2_MAX_LEN = 512;
    USBHSD->UEP3_MAX_LEN = 512;
    USBHSD->UEP4_MAX_LEN = 512;
    USBHSD->UEP5_MAX_LEN = 512;
    USBHSD->UEP6_MAX_LEN = 512;
    USBHSD->UEP7_MAX_LEN = 512;
    USBHSD->UEP8_MAX_LEN = 512;
    USBHSD->UEP9_MAX_LEN = 512;
    USBHSD->UEP10_MAX_LEN = 512;
    USBHSD->UEP11_MAX_LEN = 512;
    USBHSD->UEP12_MAX_LEN = 512;
    USBHSD->UEP13_MAX_LEN = 512;
    USBHSD->UEP14_MAX_LEN = 512;
    USBHSD->UEP15_MAX_LEN = 512;

    /* 端点DMA地址配置 */
    USBHSD->UEP0_DMA = (UINT32)(UINT8 *)EP0_Databuf;
    USBHSD->UEP1_TX_DMA = (UINT32)(UINT8 *)EP1_Tx_Databuf;
    USBHSD->UEP1_RX_DMA = (UINT32)(UINT8 *)EP1_Rx_Databuf;

    /* 端点控制寄存器配置 */
    USBHSD->UEP0_TX_LEN = 0;
    USBHSD->UEP0_TX_CTRL = USBHS_EP_T_RES_NAK;
    USBHSD->UEP0_RX_CTRL = USBHS_EP_R_RES_ACK;

    USBHSD->UEP1_TX_LEN = 0;
    USBHSD->UEP1_TX_CTRL = USBHS_EP_T_RES_NAK;
    USBHSD->UEP1_RX_CTRL = USBHS_EP_R_RES_ACK;

    USBHSD->UEP2_TX_LEN = 0;
    USBHSD->UEP2_TX_CTRL = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK;
    USBHSD->UEP2_RX_CTRL = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_ACK;

    USBHSD->UEP3_TX_LEN = 0;
    USBHSD->UEP3_TX_CTRL = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK;
    USBHSD->UEP3_RX_CTRL = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_ACK;

    USBHSD->UEP4_TX_LEN = 0;
    USBHSD->UEP4_TX_CTRL = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK;
    USBHSD->UEP4_RX_CTRL = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_ACK;

    USBHSD->UEP5_TX_LEN = 0;
    USBHSD->UEP5_TX_CTRL = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK;
    USBHSD->UEP5_RX_CTRL = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_ACK;

    USBHSD->UEP6_TX_LEN = 0;
    USBHSD->UEP6_TX_CTRL = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK;
    USBHSD->UEP6_RX_CTRL = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_ACK;

    USBHSD->UEP7_TX_LEN = 0;
    USBHSD->UEP7_TX_CTRL = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK;
    USBHSD->UEP7_RX_CTRL = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_ACK;

    USBHSD->UEP8_TX_LEN = 0;
    USBHSD->UEP8_TX_CTRL = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK;
    USBHSD->UEP8_RX_CTRL = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_ACK;

    USBHSD->UEP9_TX_LEN = 0;
    USBHSD->UEP9_TX_CTRL = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK;
    USBHSD->UEP9_RX_CTRL = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_ACK;

    USBHSD->UEP10_TX_LEN = 0;
    USBHSD->UEP10_TX_CTRL = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK;
    USBHSD->UEP10_RX_CTRL = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_ACK;

    USBHSD->UEP11_TX_LEN = 0;
    USBHSD->UEP11_TX_CTRL = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK;
    USBHSD->UEP11_RX_CTRL = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_ACK;

    USBHSD->UEP12_TX_LEN = 0;
    USBHSD->UEP12_TX_CTRL = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK;
    USBHSD->UEP12_RX_CTRL = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_ACK;

    USBHSD->UEP13_TX_LEN = 0;
    USBHSD->UEP13_TX_CTRL = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK;
    USBHSD->UEP13_RX_CTRL = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_ACK;

    USBHSD->UEP14_TX_LEN = 0;
    USBHSD->UEP14_TX_CTRL = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK;
    USBHSD->UEP14_RX_CTRL = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_ACK;

    USBHSD->UEP15_TX_LEN = 0;
    USBHSD->UEP15_TX_CTRL = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK;
    USBHSD->UEP15_RX_CTRL = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_ACK;
}

/*********************************************************************
 * @fn      USBHS_Device_Init
 *
 * @brief   USB2.0高速设备初始化
 *
 * @return  none
 */
void USBHS_Device_Init(FunctionalState sta)
{
    if (sta)
    {
        /* 配置DMA、速度、端点使能等 */
        USBHSD->HOST_CTRL = 0x00;
        USBHSD->HOST_CTRL = USBHS_SUSPENDM;

        USBHSD->CONTROL = 0;
#if IF_FULL_SPEED == 0 //切换高速全速  配置端点大小64；
        USBHSD->CONTROL = USBHS_DMA_EN | USBHS_INT_BUSY_EN | USBHS_HIGH_SPEED;
#else
        USBHSD->CONTROL = USBHS_DMA_EN | USBHS_INT_BUSY_EN | USBHS_FULL_SPEED;
#endif

        USBHSD->INT_EN = 0;
        USBHSD->INT_EN = USBHS_SETUP_ACT_EN | USBHS_TRANSFER_EN | USBHS_DETECT_EN | USBHS_SUSPEND_EN;

        /* ALL endpoint enable */
        USBHSD->ENDP_CONFIG = 0xffffffff;

        /* USB2.0高速设备端点初始化 */
        USBHS_Device_Endp_Init();
        Delay_Us(10);

        /* 使能USB连接 */
        USBHSD->CONTROL |= USBHS_DEV_PU_EN;
    }
    else
    {
        USBHSD->CONTROL &= ~USBHS_DEV_PU_EN;
        USBHSD->CONTROL |= USBHS_ALL_CLR | USBHS_FORCE_RST;
    }
}

/*********************************************************************
 * @fn      Ep1_Tx
 *
 * @brief   USBHS 端点1上传
 *
 * @return  none
 */
void Ep1_Tx(PUINT8 data, UINT8 len)
{
    memcpy(EP1_Tx_Databuf, data, len);
    USBHS_Endp1_Up_Flag = 1;
    USBHSD->UEP1_TX_LEN = len;
    USBHSD->UEP1_TX_CTRL = (USBHSD->UEP1_TX_CTRL & ~(USBHS_EP_T_RES_MASK | USBHS_EP_T_TOG_MASK)) | USBHS_EP_T_RES_ACK;
    USBHSD->UEP1_TX_CTRL |= (USBHS_Endp1_T_Tog ? USBHS_EP_T_TOG_1 : USBHS_EP_T_TOG_0);
    USBHS_Endp1_T_Tog ^= 1;
}

/*********************************************************************
 * @fn      USBHS_Device_SetAddress
 *
 * @brief   USB2.0高速设备设置设备地址
 *
 * @return  none
 */
void USBHS_Device_SetAddress(UINT32 address)
{
    USBHSD->DEV_AD = 0;
    USBHSD->DEV_AD = address & 0xff;
}

/*********************************************************************
 * @fn      USBHS_IRQHandler
 *
 * @brief   This function handles USBHS exception.
 *
 * @return  none
 */

void USBHS_IRQHandler(void)
{
    UINT32 end_num;
    UINT32 rx_token;
    UINT16 len = 0x00;
    UINT16 rx_len = 0;
    UINT8 errflag = 0x00;
    UINT8 chtype;

    USBHS_Int_Flag = USBHSD->INT_FG;
    //    printf("USB中断触发 %d\n",USBHS_Int_Flag);

    if (USBHS_Int_Flag & USBHS_TRANSFER_FLAG)
    {

        /* 端点传输处理 */
        end_num = (USBHSD->INT_ST) & MASK_UIS_ENDP;
        rx_token = (((USBHSD->INT_ST) & MASK_UIS_TOKEN) >> 4) & 0x03;
        //    printf("USB Tx: %x %x %x\n",end_num,rx_token,USBHS_Dev_SetupReqCode);
#if 0
        if( !( USBHS->STATUS & TOG_MATCH ) )
        {
            DUG_PRINTF(" TOG MATCH FAIL : ENDP %x token %x \n", end_num, rx_token);
        }
#endif
        if (end_num == 0)
        {
            /* 端点0处理 */
            if (rx_token == PID_IN)
            {
                /* 端点0上传成功中断 */
                //                printf("USB中断触发 %d\n",USBHS_Dev_SetupReqCode);

                switch (USBHS_Dev_SetupReqCode)
                {
                case USB_SET_ADDRESS:
                    USBHS_Device_SetAddress(USBHS_Dev_Address);
                    USBHSD->UEP0_TX_LEN = 0;
                    USBHSD->UEP0_TX_CTRL = 0;
                    USBHSD->UEP0_RX_CTRL = 0;
                    break;
                case USB_GET_DESCRIPTOR:
                    len = USBHS_Dev_SetupReqLen >= USBHS_UEP0_SIZE ? USBHS_UEP0_SIZE : USBHS_Dev_SetupReqLen;
                    memcpy(EP0_Databuf, pDescr, len);
                    USBHS_Dev_SetupReqLen -= len;
                    pDescr += len;
                    USBHS_Dev_Endp0_Tog ^= 1;
                    USBHSD->UEP0_TX_LEN = len;
                    USBHSD->UEP0_TX_CTRL = USBHS_EP_T_RES_ACK | (USBHS_Dev_Endp0_Tog ? USBHS_EP_T_TOG_0 : USBHS_EP_T_TOG_1);
                    break;
                default:
                    /* 状态阶段完成中断或者是强制上传0长度数据包结束控制传输 */
                    USBHSD->UEP0_RX_CTRL = USBHS_EP_R_RES_ACK | USBHS_EP_R_TOG_1;
                    pDescr = NULL;
                    //                        printf("结束控制传输  %d \n",USBHS_Dev_SetupReqCode);
                    break;
                }
            }
            else if (rx_token == PID_OUT)
            {
                switch (EP0_Databuf[0])
                {
                case 0x01:
                    break;
                default:
                    break;
                }
                USBHSD->UEP0_TX_LEN = 0;
                USBHSD->UEP0_TX_CTRL = USBHS_EP_T_RES_ACK | USBHS_EP_T_TOG_1;
                //                USBHSD->UEP2_RX_CTRL = USBHS_EP_R_RES_ACK | USBHS_EP_R_TOG_0;
            }
        }
        else if (end_num == 1)
        {
            if (rx_token == PID_IN)
            {
                USBHS_Endp1_Up_Flag = 0x00;
                // printf("tx 0\n");
                /* 默认回NAK */
                USBHSD->UEP1_TX_CTRL = (USBHSD->UEP1_TX_CTRL & ~(USBHS_EP_T_RES_MASK | USBHS_EP_T_TOG_MASK)) | USBHS_EP_T_RES_NAK;
            }
            else if (rx_token == PID_OUT)
            {
                rx_len = USBHSD->RX_LEN;
                switch (EP1_Rx_Databuf[0])
                {
                case 0x01:
                    break;
                case 0x02:
                    FLASH_WRITE_SUCCESS(EP1_Rx_Databuf[1]);
                    break;
                case 0x03:
                    // printf("rx_len :%d\n",USBHSD->RX_LEN);
                    SystemUpdate((UPDATA *)EP1_Rx_Databuf);
                    break;
                default:
                    printf("out_nak\n");
                    USBHSD->UEP1_RX_CTRL = (USBHSD->UEP1_RX_CTRL & ~USBHS_EP_R_RES_MASK) | USBHS_EP_R_RES_NAK;
                    break;
                }
                USBHSD->UEP1_RX_CTRL = (USBHSD->UEP1_RX_CTRL & ~(USBHS_EP_T_RES_MASK | USBHS_EP_T_TOG_MASK)) | USBHS_EP_R_RES_ACK | USBHS_Endp1_R_Tog ? USBHS_EP_R_TOG_1 : USBHS_EP_R_TOG_0;
            }
        }
        USBHSD->INT_FG = USBHS_TRANSFER_FLAG;
    }
    else if (USBHS_Int_Flag & USBHS_SETUP_FLAG)
    {
        //        printf("USB中断触发 SETUP\n");
        //        Delay_Us(500);
        /* SETUP包处理 */
        USBHS_Dev_SetupReqLen = pMySetupReqPak->wLength;
        USBHS_Dev_SetupReqCode = pMySetupReqPak->bRequest;
        chtype = pMySetupReqPak->bRequestType;
        len = 0x00;
        errflag = 0x00;
#if 0
        /* 打印当前Usbsetup命令  */
        printf("%02X ", pMySetupReqPak->bRequestType);
        printf("%02X ", pMySetupReqPak->bRequest);
        printf("%04X ", pMySetupReqPak->wValue);
        printf("%04X ", pMySetupReqPak->wIndex);
        printf("%04X\n ", pMySetupReqPak->wLength);
#endif
        /* 判断当前是标准请求还是其他请求 */
        if ((pMySetupReqPak->bRequestType & USB_REQ_TYP_MASK) != USB_REQ_TYP_STANDARD)
        {
            /* 其它请求,如类请求,产商请求等 */
            if (pMySetupReqPak->bRequestType & 0x40)
            {
                /* 厂商请求 */
                switch (USBHS_Dev_SetupReqCode)
                {
                default:
                    errflag = 0xFF; /* 操作失败 */
                    break;
                }
            }
            else if (pMySetupReqPak->bRequestType & 0x20)
            {
                /* HID类请求 */
                switch (USBHS_Dev_SetupReqCode)
                {
                case 0x01: // GetReport
                    // USB_Printf("GetReport %x %x %x %x %x %x\n", EP0_Databuf[1], pMySetupReqPak->bRequestType, pMySetupReqPak->bRequest, pMySetupReqPak->wValue, pMySetupReqPak->wIndex, pMySetupReqPak->wLength);
                    switch (pMySetupReqPak->wValue & 0xff)
                    {
                    case 1:
                        break;
                    case 2:

                        break;
                    case 3:

                        break;
                    default:
                        break;
                    }
                    break;
                case 0x02: // GetIdle
                    break;
                case 0x03: // GetProtocol
                    break;
                case 0x09: // SetReport
                    break;
                case 0x0A: // SetIdle
                    break;
                case 0x0B: // SetProtocol
                    break;
                default:
                    errflag = 0xFF;
                    break;
                }
            }

            /* 判断是否可以正常处理 */
            if (errflag != 0xFF)
            {
                //             printf("判断是否可以正常处理\n");
                if (USBHS_Dev_SetupReqLen > len)
                {
                    USBHS_Dev_SetupReqLen = len;
                }
                len = (USBHS_Dev_SetupReqLen >= USBHS_UEP0_SIZE) ? USBHS_UEP0_SIZE : USBHS_Dev_SetupReqLen;
                memcpy(EP0_Databuf, pDescr, len);
                pDescr += len;
            }
        }
        else
        {
            /* 处理标准USB请求包 */
            switch (USBHS_Dev_SetupReqCode)
            {
            case USB_GET_DESCRIPTOR:
            {
                switch (((pMySetupReqPak->wValue) >> 8))
                {
                case USB_DESCR_TYP_DEVICE:
                    /* 获取设备描述符 */
                    pDescr = MyDevDescr;
                    len = MyDevDescr[0];
                    break;

                case USB_DESCR_TYP_CONFIG:
                    /* 获取配置描述符 */
                    MyCfgDescr_HS[25] = (sizeof(reprot) & 0xFF);
                    MyCfgDescr_HS[26] = (sizeof(reprot) >> 8);
                    pDescr = MyCfgDescr_HS;
                    len = MyCfgDescr_HS[2] | ((UINT16)MyCfgDescr_HS[3] << 8);
                    break;

                case USB_DESCR_TYP_STRING:
                    /* 获取字符串描述符 */
                    switch ((pMySetupReqPak->wValue) & 0xff)
                    {
                    case 0:
                        /* 语言字符串描述符 */
                        pDescr = MyLangDescr;
                        len = MyLangDescr[0];
                        break;

                    case 1:
                        /* USB产商字符串描述符 */
                        pDescr = MyManuInfo;
                        len = sizeof(MyManuInfo);
                        break;

                    case 2:
                        /* USB产品字符串描述符 */
                        pDescr = MyProdInfo;
                        len = sizeof(MyProdInfo);
                        break;

                    case 3:
                        /* USB序列号字符串描述符 */
                        pDescr = MySerNumInfo;
                        len = sizeof(MySerNumInfo);
                        break;

                    default:
                        errflag = 0xFF;
                        break;
                    }
                    break;

                case USB_DESCR_TYP_REPORT:
                    /* USB设备报告描述符 */
                    pDescr = reprot;
                    len = sizeof(reprot);

                    break;

                case USB_DESCR_TYP_QUALIF:
                    /* 设备限定描述符 */
                    pDescr = (PUINT8)&MyUSBQUADesc[0];
                    len = sizeof(MyUSBQUADesc);
                    break;

                case USB_DESCR_TYP_SPEED:
                    /* 其他速度配置描述符 */
                    if (USBHS_Dev_Speed == 0x01)
                    {
                        /* 高速模式 */
                        memcpy(&TAB_USB_HS_OSC_DESC[2], &MyCfgDescr_HS[2], sizeof(MyCfgDescr_HS) - 2);
                        pDescr = (PUINT8)&TAB_USB_HS_OSC_DESC[0];
                        len = sizeof(TAB_USB_HS_OSC_DESC);
                    }
                    else
                    {
                        errflag = 0xFF;
                    }
                    break;

                case USB_DESCR_TYP_BOS:
                    /* BOS描述符 */
                    /* USB2.0设备不支持BOS描述符 */
                    errflag = 0xFF;
                    break;
                default:
                    errflag = 0xFF;
                    break;
                }

                /* 判断是否可以正常处理 */
                if (errflag != 0xFF)
                {
                    if (USBHS_Dev_SetupReqLen > len)
                    {
                        USBHS_Dev_SetupReqLen = len;
                    }
                    len = (USBHS_Dev_SetupReqLen >= USBHS_UEP0_SIZE) ? USBHS_UEP0_SIZE : USBHS_Dev_SetupReqLen;
                    memcpy(EP0_Databuf, pDescr, len);
                    pDescr += len;
                }
            }
            break;

            case USB_SET_ADDRESS:
                /* 设置地址 */
                USBHS_Dev_Address = (pMySetupReqPak->wValue) & 0xff;
                break;

            case USB_GET_CONFIGURATION:
                /* 获取配置值 */
                EP0_Databuf[0] = USBHS_Dev_Config;
                if (USBHS_Dev_SetupReqLen > 1)
                {
                    USBHS_Dev_SetupReqLen = 1;
                }
                break;

            case USB_SET_CONFIGURATION:
                /* 设置配置值 */
                USBHS_Dev_Config = (pMySetupReqPak->wValue) & 0xff;
                USBHS_Dev_EnumStatus = 0x01;
                break;

            case USB_CLEAR_FEATURE:
                /* 清除特性 */
                if ((pMySetupReqPak->bRequestType & USB_REQ_RECIP_MASK) == USB_REQ_RECIP_ENDP)
                {
                    /* 清除端点 */
                    switch ((pMySetupReqPak->wIndex) & 0xff) /* wIndexL */
                    {
                    case 0x82:
                        /* SET Endp2 Tx to USBHS_EP_T_RES_NAK;USBHS_EP_T_TOG_0;len = 0 */
                        USBHSD->UEP2_TX_LEN = 0;
                        USBHSD->UEP2_TX_CTRL = USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0;
                        break;

                    case 0x02:
                        /* SET Endp2 Rx to USBHS_EP_R_RES_ACK;USBHS_EP_R_TOG_0 */
                        USBHSD->UEP2_TX_CTRL = USBHS_EP_R_RES_ACK | USBHS_EP_R_TOG_0;
                        break;

                    case 0x81:
                        /* SET Endp1 Tx to USBHS_EP_T_RES_NAK;USBHS_EP_T_TOG_0;len = 0 */
                        USBHSD->UEP1_TX_LEN = 0;
                        USBHSD->UEP1_TX_CTRL = USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0;
                        break;

                    case 0x01:
                        /* SET Endp1 Rx to USBHS_EP_R_RES_NAK;USBHS_EP_R_TOG_0 */
                        USBHSD->UEP1_RX_CTRL = USBHS_EP_R_RES_ACK | USBHS_EP_R_TOG_0;
                        break;

                    default:
                        errflag = 0xFF;
                        break;
                    }
                }
                else if ((pMySetupReqPak->bRequestType & USB_REQ_RECIP_MASK) == USB_REQ_RECIP_DEVICE)
                {
                    if (((pMySetupReqPak->wValue) & 0xff) == 1) /* wIndexL */
                    {
                        USBHS_Dev_SleepStatus &= ~0x01;
                    }
                }
                else
                {
                    errflag = 0xFF;
                }
                break;

            case USB_SET_FEATURE:
                /* 设置特性 */
                if ((pMySetupReqPak->bRequestType & 0x1F) == 0x00)
                {
                    /* 设置设备 */
                    if (pMySetupReqPak->wValue == 0x01)
                    {
                        if (MyCfgDescr_HS[7] & 0x20)
                        {
                            /* 设置唤醒使能标志 */
                            USBHS_Dev_SleepStatus = 0x01;
                        }
                        else
                        {
                            errflag = 0xFF;
                        }
                    }
                    else
                    {
                        errflag = 0xFF;
                    }
                }
                else if ((pMySetupReqPak->bRequestType & 0x1F) == 0x02)
                {
                    /* 设置端点 */
                    if (pMySetupReqPak->wValue == 0x00)
                    {
                        /* 设置指定端点STALL */
                        switch ((pMySetupReqPak->wIndex) & 0xff)
                        {
                        case 0x82:
                            /* 设置端点2 IN STALL */
                            USBHSD->UEP2_TX_CTRL = (USBHSD->UEP2_TX_CTRL & ~USBHS_EP_T_RES_MASK) | USBHS_EP_T_RES_STALL;
                            break;

                        case 0x02:
                            /* 设置端点2 OUT Stall */
                            USBHSD->UEP2_RX_CTRL = (USBHSD->UEP2_RX_CTRL & ~USBHS_EP_R_RES_MASK) | USBHS_EP_R_RES_STALL;
                            break;

                        case 0x81:
                            /* 设置端点1 IN STALL */
                            USBHSD->UEP1_TX_CTRL = (USBHSD->UEP1_TX_CTRL & ~USBHS_EP_T_RES_MASK) | USBHS_EP_T_RES_STALL;
                            break;

                        case 0x01:
                            /* 设置端点1 OUT STALL */
                            USBHSD->UEP1_RX_CTRL = (USBHSD->UEP1_RX_CTRL & ~USBHS_EP_R_RES_MASK) | USBHS_EP_R_RES_STALL;
                            break;

                        default:
                            errflag = 0xFF;
                            break;
                        }
                    }
                    else
                    {
                        errflag = 0xFF;
                    }
                }
                else
                {
                    errflag = 0xFF;
                }
                break;

            case USB_GET_INTERFACE:
                EP0_Databuf[0] = 0x00;
                if (USBHS_Dev_SetupReqLen > 1)
                {
                    USBHS_Dev_SetupReqLen = 1;
                }
                break;

            case USB_SET_INTERFACE:
                EP0_Databuf[0] = 0x00;
                if (USBHS_Dev_SetupReqLen > 1)
                {
                    USBHS_Dev_SetupReqLen = 1;
                }
                break;

            case USB_GET_STATUS:
                /* 根据当前端点实际状态进行应答 */
                EP0_Databuf[0] = 0x00;
                EP0_Databuf[1] = 0x00;
                if (pMySetupReqPak->wIndex == 0x81)
                {
                    if ((USBHSD->UEP1_TX_CTRL & USBHS_EP_T_RES_MASK) == USBHS_EP_T_RES_STALL)
                    {
                        EP0_Databuf[0] = 0x01;
                    }
                }
                else if (pMySetupReqPak->wIndex == 0x01)
                {
                    if ((USBHSD->UEP1_RX_CTRL & USBHS_EP_R_RES_MASK) == USBHS_EP_R_RES_STALL)
                    {
                        EP0_Databuf[0] = 0x01;
                    }
                }
                else if (pMySetupReqPak->wIndex == 0x82)
                {
                    if ((USBHSD->UEP2_TX_CTRL & USBHS_EP_T_RES_MASK) == USBHS_EP_T_RES_STALL)
                    {
                        EP0_Databuf[0] = 0x01;
                    }
                }
                else if (pMySetupReqPak->wIndex == 0x02)
                {
                    if ((USBHSD->UEP2_RX_CTRL & USBHS_EP_R_RES_MASK) == USBHS_EP_R_RES_STALL)
                    {
                        EP0_Databuf[0] = 0x01;
                    }
                }
                if (USBHS_Dev_SetupReqLen > 2)
                {
                    USBHS_Dev_SetupReqLen = 2;
                }
                break;

            default:
                errflag = 0xff;
                break;
            }
        }

        /* 端点0处理 */
        if (errflag == 0xFF)
        {
            /* IN - STALL / OUT - DATA - STALL */
            USBHS_Dev_SetupReqCode = 0xFF;
            USBHSD->UEP0_TX_LEN = 0;
            USBHSD->UEP0_TX_CTRL = USBHS_EP_T_RES_STALL;
            USBHSD->UEP0_RX_CTRL = USBHS_EP_R_RES_STALL;
        }
        else
        {
            /* DATA stage (IN -DATA1-ACK) */
            if (chtype & 0x80)
            {
                len = (USBHS_Dev_SetupReqLen > USBHS_UEP0_SIZE) ? USBHS_UEP0_SIZE : USBHS_Dev_SetupReqLen;
                USBHS_Dev_SetupReqLen -= len;
            }
            else
            {
                len = 0;
            }
            USBHSD->UEP0_TX_LEN = len;
            USBHSD->UEP0_TX_CTRL = USBHS_EP_T_RES_ACK | USBHS_EP_T_TOG_1;
        }
        USBHSD->INT_FG = USBHS_SETUP_FLAG;
    }
    else if (USBHS_Int_Flag & USBHS_DETECT_FLAG)
    {
        /* USB总线复位中断 */
//        printf("USB中断触发 复位\n");
#if 0
        printf("Rs\n");

#endif
        USBHS_Dev_Address = 0x00;
        USBHS_Device_Endp_Init();                   /* USB2.0高速设备端点初始化 */
        USBHS_Device_SetAddress(USBHS_Dev_Address); /* USB2.0高速设备设置设备地址 */
        USBHSD->INT_FG = USBHS_DETECT_FLAG;
    }
    else if (USBHS_Int_Flag & USBHS_SUSPEND_FLAG)
    {
        /* 唤醒 */
//        printf("USB中断触发 唤醒\n");
#if 0
        printf("USB SUSPEND!!!\n");
#endif
        USBHS_Dev_SleepStatus &= ~0x02;
        USBHS_Dev_EnumStatus = 0x01;
        USBHSD->INT_FG = USBHS_SUSPEND_FLAG;
    }
}